﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JeanFish.Blog.Business
{
    public sealed class Post : PostBase
    {
        internal async void LoadAsync()
        {
            this.Author = await BlogService.Current.GetPostAuthorAsync(this);
        }
        private Blog blog = null;
        public Post(Blog blog)
            : this(blog, true)
        { }
        internal Post(Blog blog, bool isNew)
        {
            this.IsNew = isNew;
            this.Blog = blog;
            this.Author = this.Blog.Onwer;
            //this.Blog.Saved += Blog_Saved;
            //this.Saved += this.Blog.Post_Saved;
        }
        public static implicit operator Post(Storage.Post post)
        {
            var p = new Post(new Blog
            {
                Name = post.Blog
            },false);
            p.Copy(post);
            return p;
        }
        internal void Blog_Saved(object sender, SavedEventArgs e)
        {
            if (e.Result == SavedResult.OK)
                this.AcceptChanges();
        }
        public bool IsNew { get; internal set; }
        public Guid ID
        {
            get { return Guid.Parse(this._id); }
            set
            {

                this.SetProperty<string>("ID", value.ToString("N"), ref this._id);
            }
        }
        public string Title
        {
            get { return this._title; }
            set
            {
                this.SetProperty<string>("Title", value, ref this._title);
            }
        }
        public string Text
        {
            get { return this._text; }
            set
            {
                this.SetProperty<string>("Text", value, ref this._text);
            }
        }
        public DateTime CreatedTime
        {
            get { return new DateTime(this._created, DateTimeKind.Utc).ToLocalTime(); }
            set
            {
                this.SetProperty<long>("CreateTime", value.ToUniversalTime().Ticks, ref this._created);
            }
        }
        public DateTime ModifiedTime
        {
            get { return new DateTime(this._modified, DateTimeKind.Utc).ToLocalTime(); }
            set
            {
                this.SetProperty<long>("ModifiedTime", value.ToUniversalTime().Ticks, ref this._modified);
            }
        }
        public User Author
        {
            get
            {
                return BlogService.Current.GetPostAuthorAsync(this).Result;
            }
            set
            {
                this.SetProperty<string>("Author", value.ID.ToString("N"), ref this._author);
            }
        }

        public Blog Blog
        {
            get
            {
                return this.blog;
            }
            set
            {
                this.blog = value;
                this.SetProperty<String>("Blog", value.ID.ToString("N"), ref this._blog);
            }
        }
        public PostLabel Labels
        {
            get { return (PostLabel)this._label; }
            set
            {
                this.SetProperty<long>("Labels", (long)value, ref this._label);
            }
        }

        public void Delete()
        {
            this.Labels |= PostLabel.Deleted;
        }
        public sealed override void AcceptChanges()
        {
            base.AcceptChanges();
        }

        protected async override Task<SavedResult> SaveAsync()
        {
            if (IsChanged)
            {
                if (IsNew)
                {
                    this.ModifiedTime = this.CreatedTime;
                    return await BlogService.Current.CreatePostAsync(this);
                }
                else
                {
                    this.ModifiedTime = DateTime.UtcNow;
                    return await BlogService.Current.UpdatePostAsync(this);
                }
            }
            else
                return SavedResult.OK;
        }
    }
}
